package com.cinema.servlet.admin;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;

/**
 * 图片上传Servlet
 */
@MultipartConfig(
    fileSizeThreshold = 1024 * 1024 * 2, // 2MB
    maxFileSize = 1024 * 1024 * 10,      // 10MB
    maxRequestSize = 1024 * 1024 * 50    // 50MB
)
public class ImageUploadServlet extends HttpServlet {

    private static final String UPLOAD_DIR = "images/movies";
    private static final String PROJECT_ROOT = "D:\\project\\java\\cinema-booking-system\\src\\main\\webapp";

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        try {
            // 获取上传的文件
            Part filePart = request.getPart("file");

            if (filePart == null || filePart.getSize() == 0) {
                out.print("{\"success\": false, \"message\": \"请选择要上传的文件\"}");
                return;
            }

            String fileName = getFileName(filePart);
            if (fileName == null || fileName.trim().isEmpty()) {
                out.print("{\"success\": false, \"message\": \"文件名无效\"}");
                return;
            }

            // 验证文件类型
            String contentType = filePart.getContentType();
            if (!isValidImageType(contentType)) {
                out.print("{\"success\": false, \"message\": \"只支持JPG、PNG、GIF格式的图片\"}");
                return;
            }

            // 生成唯一文件名
            String fileExtension = getFileExtension(fileName);
            String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

            // 获取两个上传目录的绝对路径
            // 1. 项目源码目录
            String sourceUploadPath = PROJECT_ROOT + File.separator + UPLOAD_DIR;
            File sourceUploadDir = new File(sourceUploadPath);

            // 2. Tomcat运行目录
            String runtimeUploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
            File runtimeUploadDir = new File(runtimeUploadPath);

            System.out.println("图片源码目录: " + sourceUploadPath);
            System.out.println("图片运行目录: " + runtimeUploadPath);

            // 如果目录不存在，创建目录
            if (!sourceUploadDir.exists()) {
                boolean created = sourceUploadDir.mkdirs();
                if (created) {
                    System.out.println("成功创建源码上传目录: " + sourceUploadPath);
                } else {
                    System.err.println("创建源码上传目录失败: " + sourceUploadPath);
                    out.print("{\"success\": false, \"message\": \"创建源码上传目录失败\"}");
                    return;
                }
            }

            if (!runtimeUploadDir.exists()) {
                boolean created = runtimeUploadDir.mkdirs();
                if (created) {
                    System.out.println("成功创建运行时上传目录: " + runtimeUploadPath);
                } else {
                    System.err.println("创建运行时上传目录失败: " + runtimeUploadPath);
                    out.print("{\"success\": false, \"message\": \"创建运行时上传目录失败\"}");
                    return;
                }
            }

            // 保存到源码目录
            String sourceFilePath = sourceUploadPath + File.separator + uniqueFileName;
            filePart.write(sourceFilePath);
            System.out.println("图片已保存到源码目录: " + sourceFilePath);

            // 保存到运行时目录
            String runtimeFilePath = runtimeUploadPath + File.separator + uniqueFileName;
            try {
                // 复制文件到运行时目录
                java.nio.file.Files.copy(
                    java.nio.file.Paths.get(sourceFilePath),
                    java.nio.file.Paths.get(runtimeFilePath),
                    java.nio.file.StandardCopyOption.REPLACE_EXISTING
                );
                System.out.println("图片已复制到运行时目录: " + runtimeFilePath);
            } catch (Exception copyEx) {
                System.err.println("复制图片到运行时目录失败: " + copyEx.getMessage());
                // 不抛出异常，因为源码目录已保存成功
            }

            // 生成包含contextPath的路径用于数据库存储和前端显示
            String dbPath = "${pageContext.request.contextPath}/images/movies/" + uniqueFileName;
            String displayUrl = request.getContextPath() + "/images/movies/" + uniqueFileName;

            out.print("{\"success\": true, \"url\": \"" + displayUrl + "\", \"dbPath\": \"" + dbPath + "\", \"message\": \"上传成功\"}");

        } catch (Exception e) {
            e.printStackTrace();
            out.print("{\"success\": false, \"message\": \"上传失败：" + e.getMessage() + "\"}");
        } finally {
            out.close();
        }
    }

    /**
     * 获取文件名
     */
    private String getFileName(Part part) {
        String contentDisposition = part.getHeader("content-disposition");
        if (contentDisposition != null) {
            for (String content : contentDisposition.split(";")) {
                if (content.trim().startsWith("filename")) {
                    return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
                }
            }
        }
        return null;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            return fileName.substring(lastDotIndex);
        }
        return "";
    }

    /**
     * 验证是否为有效的图片类型
     */
    private boolean isValidImageType(String contentType) {
        return contentType != null && (
            contentType.equals("image/jpeg") ||
            contentType.equals("image/jpg") ||
            contentType.equals("image/png") ||
            contentType.equals("image/gif")
        );
    }
}
